package com.yuandian.bpm.bi.modules.quartz.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuandian.bpm.admin.api.feign.RemoteParamService;
import com.yuandian.bpm.bi.modules.quartz.enums.TaskTypeEnum;
import com.yuandian.bpm.bi.modules.quartz.mapper.ConfReportFileInfoMapper;
import com.yuandian.bpm.bi.modules.quartz.mapper.ConfReportTaskInfoMapper;
import com.yuandian.bpm.bi.modules.quartz.mapper.ConfReportTaskLogMapper;
import com.yuandian.bpm.bi.modules.quartz.service.HandelBaseService;
import com.yuandian.bpm.bi.modules.quartz.util.CronUtil;
import com.yuandian.bpm.bi.modules.quartz.util.FileUtil;
import com.yuandian.bpm.bi.modules.quartz.vo.ConfReportFileInfo;
import com.yuandian.bpm.bi.modules.quartz.vo.ConfReportTaskInfo;
import com.yuandian.bpm.bi.modules.quartz.vo.ConfReportTaskVo;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 *  <p>
 *      数据删除服务：
 * 			1.报表文件删除
 * 			2.conf_report_task_log  表数据删除
 * 		    3.conf_report_file_info 表数据删除
 * 	</p>
 *
 * @Author: LinShiHe
 * @Date: 2022/9/19 16:20
 */
@Slf4j
@Service("handelDeleteDataTaskServiceImpl")
public class HandelDeleteDataTaskServiceImpl implements HandelBaseService {

	@Autowired
	private ConfReportFileInfoMapper fileInfoMapper;

	@Autowired
	private ConfReportTaskInfoMapper taskInfoMapper;

	@Autowired
	private ConfReportTaskLogMapper logMapper;

	@Autowired
	private RemoteParamService remoteParamService;



	@Override
	public ConfReportTaskVo handleData(ConfReportTaskInfo confReportTaskInfo, JobExecutionContext context) {
		log.info("[数据删除任务]-开始执行。。。");
		long sTime = System.currentTimeMillis();
		ConfReportTaskVo resultVo = new ConfReportTaskVo();                    // 结果集
		resultVo.setTaskType(TaskTypeEnum.SYSTEM_INTERNAL.toString());        // 任务类型： 系统类


		// 1.删除表数据(conf_report_task_log 、 conf_report_file_info)
		deleteTableData();


		// 2.删除服务器报表文件
		deleteServerReportFiles(confReportTaskInfo, context);


		log.info("[数据删除任务]-本次调度结束，调度时间：{}，耗时：{} MS",
				context.getScheduledFireTime(),
				System.currentTimeMillis() - sTime);

		return new ConfReportTaskVo();
	}

	/**
	 * 删除服务器报表文件
	 */
	private void deleteServerReportFiles(ConfReportTaskInfo confReportTaskInfo, JobExecutionContext context) {
		log.info("[自定义报表]-进入删除服务器文件逻辑。。。");
		long sTime = System.currentTimeMillis();
		try {
			// 查询各个任务的文件保留次数
			ConfReportTaskInfo params = new ConfReportTaskInfo();
			Page<ConfReportTaskInfo> page = taskInfoMapper.getTaskInfoList(new Page<>(1, -1), params);

			// 循环删除服务器报表文件
			if (page != null && page.getRecords() != null) {
				List<Integer> deleteFileId = new ArrayList<>();
				for (ConfReportTaskInfo taskInfo : page.getRecords()) {
					// 查询 conf_report_file_info 把 非永久保留的文件 查询出来
					if (taskInfo.getReportFileRetentionTime() != null && taskInfo.getReportFileRetentionTime() > 0) {
						ConfReportFileInfo fileInfoParam = new ConfReportFileInfo();
						fileInfoParam.setReportFileStatus(1);
						fileInfoParam.setTaskId(taskInfo.getId());
						Integer reportFileRetentionTime = taskInfo.getReportFileRetentionTime();

						List<ConfReportFileInfo> fileInfos = fileInfoMapper.getFileInfoList(new Page<>(reportFileRetentionTime, -1), fileInfoParam);
						for (ConfReportFileInfo fileInfo : fileInfos) {
							if (StringUtil.isNotEmpty(fileInfo.getReportFilePath())) {
								deleteFileId.add(fileInfo.getId());
								FileUtil.deleteFile(fileInfo.getReportFilePath());
							}
						}
					}
				}
				if (deleteFileId.size() > 0) {
					// 更新表文件 是否删除 字段状态
					fileInfoMapper.updateFileState(deleteFileId, 0);
				}
			}
			log.error("[自定义报表]- 删除服务器文件,成功,耗时：{}", System.currentTimeMillis() - sTime);
		}catch (Exception e) {
			e.printStackTrace();
			log.error("[自定义报表]- 删除服务器文件,报错：{}", e.getMessage());
		}

	}

	/**
	 * 删除表数据
	 */
	private void deleteTableData() {
		log.info("[自定义报表]-进入删除conf_report_task_log，conf_report_file_info表数据逻辑。。。");
		long sTime = System.currentTimeMillis();
		String taskLogTableDataSaveTime = "";		// conf_report_task_log  表数据保留天数
		String fileInfoTableDataSaveTime = "";		// conf_report_file_info 表数据保留天数

		try {
			taskLogTableDataSaveTime = remoteParamService.getByKeyNoInner("taskLog.table.data.saveTime").getData();
			fileInfoTableDataSaveTime = remoteParamService.getByKeyNoInner("fileInfo.table.data.saveTime").getData();
			log.info("[自定义报表]-[远程调用-基础服务模块]-[获取公共参数配置(获取conf_report_task_log  表数据保留天数，conf_report_file_info 表数据保留天数)]-耗时: {} MS", System.currentTimeMillis() - sTime);
		} catch (Exception e) {
			log.warn("[自定义报表]-[远程调用-基础服务模块]-[获取公共参数配置(获取conf_report_task_log  表数据保留天数，conf_report_file_info 表数据保留天数)]报错: {}，采用默认值 15", e.getMessage());
		}

		// 数据保留时间-默认15天
		if (StringUtil.isBlank(taskLogTableDataSaveTime)) { taskLogTableDataSaveTime = "1"; }
		if (StringUtil.isBlank(fileInfoTableDataSaveTime)) { fileInfoTableDataSaveTime = "1"; }

		String taskLogTableDataTime = CronUtil.getBeforeDayTime(DateUtil.formatDateTime(new Date()), Integer.parseInt(taskLogTableDataSaveTime));  // 数据删除时间
		String fileInfoTableDataTime = CronUtil.getBeforeDayTime(DateUtil.formatDateTime(new Date()), Integer.parseInt(fileInfoTableDataSaveTime));  // 数据删除时间

		// 删除数据
		try {
			sTime = System.currentTimeMillis();
			int fileInfoEffectCount = fileInfoMapper.deleteTaskByTime(fileInfoTableDataTime);
			int taskLogEffectCount = logMapper.deleteTaskByTime(taskLogTableDataTime);
			log.info("[自定义报表]-删除conf_report_task_log，conf_report_file_info表数据-成功,fileInfoEffectCount: {},  taskLogEffectCount:{}, 耗时:{} Ms", fileInfoEffectCount, taskLogEffectCount, System.currentTimeMillis() - sTime);

		} catch (Exception e) {
			log.warn("[自定义报表]-删除conf_report_task_log，conf_report_file_info表数据-异常: {}", e.getMessage());
		}
	}

	@Override
	public void monitorThead(ConfReportTaskInfo confReportTaskInfo) {}

	@Override
	public void insertData(ConfReportTaskInfo confReportTaskInfo) throws Exception {}
}
